package com.neo.sk.collector

import akka.actor.{Props, Actor}
import com.neo.sk.common._
import com.neo.sk.util.{ParamsUtil, ParseUtil}
import com.neo.sk.util.http.{InputStreamUtils, DoubanLogin, HttpClientUtil}
import org.apache.http.impl.client.CloseableHttpClient
import org.apache.http.util.EntityUtils
import org.slf4j.LoggerFactory
import scala.concurrent.duration._
import scala.concurrent.Future
import scala.util.{Failure, Success}

/**
 * User: Huangshanqi
 * Date: 2015/7/13
 * Time: 12:41
 */
class FetchMovieUrlListActor(userClient: CloseableHttpClient) extends Actor{
  private val logger = LoggerFactory.getLogger(this.getClass)
  import com.neo.sk.collector.Manager.myExecutionContext
  val saveActor = context.actorOf(Props[SaveActor](new SaveActor), "SaveActor-FetchMovieUrlListActor-" + System.currentTimeMillis())
  final val httpClientUtil = new HttpClientUtil()

  private final val MaxRetryTime = 3

  //http://www.douban.com/tag/1990s/movie?start=3855&retry=1
  override def receive: Receive = {

    case UrlTask(url) =>{
      val urlSegment = url.split("\\?")
      val start = ParamsUtil.getStartFromUrl(url)
      val retryTime = ParamsUtil.getRetryTimeFromUrl(url)
      val tagPattern = "(.*)/tag/(.*)/movie(.*)".r
      val tagPattern(_,tag,_) = urlSegment(0)

      if(retryTime < MaxRetryTime){
        val f = Future {
          HttpClientUtil.executeHttpGet(url, userClient, null)
        }
        f.onComplete {
          case Success(response) => {
            try {
              val content = EntityUtils.toString(InputStreamUtils.getRealEntity(response.getEntity), "utf-8")
              val code = response.getStatusLine.getStatusCode
              logger.info("code============================= " + code)
              if (code == 200){
                if (content != null && content != "") {
                  val result = ParseUtil.parseMovieUrlList(content)
                  val resultSize = result.size
                  if(result!=null && resultSize>0){
                    saveActor ! SaveUrlList(result,tag)
                    val newPage = urlSegment(0) + "?start=" + (start + 15) + "&retry=1"
                    self ! RetryWithDelay(newPage,5)
                  }else{
                    //finish
                    context.parent ! FinishFetchByTag(url)
                  }
                } else {
                  logger.info("code==== " + code + " with url " + url)
                  val retryUrl = urlSegment(0) + "?start=" + start + "&retry=" + (retryTime + 1)
                  self ! Retry(retryUrl)
                }
              }else{
                val retryUrl = urlSegment(0) + "?start=" + start + "&retry=" + (retryTime + 1)
                self ! Retry(retryUrl)
              }
              EntityUtils.consume(response.getEntity)
              response.close()
            }catch {
              case e:Exception =>
                logger.info(e.getMessage,e)
                val retryUrl = urlSegment(0) + "?start=" + start + "&retry=" + (retryTime + 1)
                self ! Retry(retryUrl)
            }
          }
          case Failure(e) =>{
            val retryUrl = urlSegment(0) + "?start=" + start + "&retry=" + (retryTime + 1)
            self ! Retry(retryUrl)
          }
        }
      }else{
        logger.info("get url:" + url + " more than " + MaxRetryTime +" times and fail")
        //finish
        context.parent ! FinishFetchByTag(url)
      }
    }
    case Retry(url) =>{
      context.system.scheduler.scheduleOnce(5 seconds,self,UrlTask(url))
    }
    case RetryWithDelay(url,delaySecond) =>{
      context.system.scheduler.scheduleOnce(delaySecond seconds,self,UrlTask(url))
    }
    case unknow@_ => logger.info("unknow message: "+ unknow + "  in " + context.self.path.name + " from " + context.sender().path.name)
  }
}
